#ifndef SERIAL_PORT
#define	SERIAL_PORT

// ***************************************************************************
// CHANGE LOG
//
// ***************************************************************************

// ***************************************************************************
// ***************************************************************************
// Section: Includes
// ***************************************************************************
// ***************************************************************************
#include <string>
#include <vector>

// ***************************************************************************
// ***************************************************************************
// Section: Constants & Data Types
// ***************************************************************************
// ***************************************************************************
#ifndef PB_CLK
#warning "PB_CLK not defined, defaulting to 80E6"
#define PB_CLK 80E6
#endif


/*! \brief Represents a serial port resource.
 *
 *  Use this class to control a serial port resource. This class provides
 * synchronous and event-driven I/O, and access to serial driver properties.
 */
class SerialPort
{
public:
	// Data Structers and enums

	/*! \brief Represents a Serial Port buffer
	 *
	 */
	struct SerialPortBuffer
	{
		UART_MODULE portId;
		std::string buffer;
		bool messageReady;
	};

	/*! \brief Delimiters used during module communications
	 */
	enum class Delimiters
	{
		Eot = 0x04, /*!< End of Transmission */
				Gs = 0x1D, /*!< Group Seperator */
				Rs = 0x1E, /*!< Record Seperator */
				Zero = 0x00 /*!<Zero (Null) Seperator */
	};


	// Static Methods
	static void AppendBuffer(const UART_MODULE portId, const BYTE data);
	static std::string ReadBuffer(const UART_MODULE portId);
	static void ClearBuffer(const UART_MODULE portId);
	static struct SerialPort::SerialPortBuffer* GetBuffer(const UART_MODULE portId);

	// Constructors
	SerialPort(const UART_MODULE portId);
	SerialPort(const UART_MODULE portId, const UINT32 baudRate);

	// Destructors
	virtual ~SerialPort();

	// Methods
	struct SerialPort::SerialPortBuffer* GetBuffer();
	void ProcessBuffer();

	void Write(const BYTE data);
	void Write(const BYTE *buffer, const UINT32 length);
	void Write(const BYTE *buffer, const UINT32 index, const UINT32 length);
	void Write(const std::string data);

	bool GetInvertedPolarity();

	void Open();

	void Close();

	void SetBaudRate(const UINT32 baudRate);
	void ClearBuffer();

private:
	// Static Attributes
	static std::vector<struct SerialPortBuffer *> _buffers;

	// Attributes
	UART_MODULE _portId;
	UINT32 _baudRate;
	struct SerialPortBuffer _buffer;
	bool _invertPolarity;

	// Methods
	void Initialize(const UART_MODULE portId, const UINT32 baudRate);
};

#endif

